package it.polimi.reTravelDream.beans;

import it.polimi.reTravelDream.dto.CityDTO;
import it.polimi.reTravelDream.dto.ExcursionDTO;
import it.polimi.reTravelDream.dto.FlightDTO;
import it.polimi.reTravelDream.dto.HotelDTO;
import it.polimi.reTravelDream.dto.TravelPackageDTO;
import it.polimi.reTravelDream.eao.CityEAOLocal;
import it.polimi.reTravelDream.eao.ExcursionEAOLocal;
import it.polimi.reTravelDream.eao.FlightEAOLocal;
import it.polimi.reTravelDream.eao.HotelEAOLocal;
import it.polimi.reTravelDream.eao.PackageCreationEAOLocal;
import it.polimi.reTravelDream.eao.TravelPackageActionEAOLocal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;

import org.primefaces.expression.impl.ThisExpressionResolver;

@ManagedBean(name="packageCreation")
@ViewScoped

public class PackageCreationBean {
	
	@EJB
	private PackageCreationEAOLocal packageCreation;
	
	@EJB 
	private FlightEAOLocal flightEAOLocal;
	
	@EJB
	private HotelEAOLocal hotelEAOLocal;
	
	@EJB
	private ExcursionEAOLocal excursionEAOLocal;
	
	@EJB
	private TravelPackageActionEAOLocal travelPackageActionEAOLocal;
	
	@EJB
	private CityEAOLocal cityEAOLocal;
	
	private List<CityDTO> cityDTOs;
	
	private TravelPackageDTO travelPackageDTO;

	private List<FlightDTO> allflights;
	private List<HotelDTO> allHotels;
	private List<ExcursionDTO> allExcursion;
	
	private HashMap<Integer,Boolean> isAddFlight;
	private HashMap<Integer,FlightDTO> flightToAdd;
	
	private HashMap<Integer,Boolean> isAddhotel;
	private HashMap<Integer,HotelDTO> hotelsToAdd;	
	
	private HashMap<Integer, Boolean> isAddExcursion;
	private HashMap<Integer, ExcursionDTO> excursionToAdd;
	
	private String errorHotel;
	private String errorFlight;
	private String errorExcursion;
	
	private String errorPackageId;
	private String errorNumberPerson;
	private String errorIdAlreadyExist;
	private String errorNameAlreadyExist;
	
	private boolean isConfirmCreation;
	private boolean isExcursion;
	
	 public PackageCreationBean() {
		 this.cityDTOs=new ArrayList<CityDTO>();
		 this.isConfirmCreation=false;
		 this.isAddhotel=new HashMap<Integer,Boolean>();
		 this.hotelsToAdd=new HashMap<Integer,HotelDTO>();
		 
		 this.isAddExcursion=new HashMap<Integer,Boolean>();
		 this.excursionToAdd=new HashMap<Integer,ExcursionDTO>();
		 
		 this.flightToAdd=new HashMap<Integer,FlightDTO>();
		 this.isAddFlight=new HashMap<Integer,Boolean>();
		 this.travelPackageDTO=new TravelPackageDTO();

		 this.allflights=new ArrayList<FlightDTO>();
		 this.allHotels=new ArrayList<HotelDTO>();
		 this.allExcursion=new ArrayList<ExcursionDTO>();
	 }
	 
	 @PostConstruct
	 public void inizialize(){
		 this.cityDTOs=cityEAOLocal.getAllCity();
		 
		 List<FlightDTO> tempDtos=this.flightEAOLocal.getAllFlights();
		 for(FlightDTO f:tempDtos){
			 if (f.isActive()) {
				 this.allflights.add(f);
			}
		 }
		 
		 for (FlightDTO fDto:this.allflights){
				 this.isAddFlight.put(fDto.getId(), true);
		 }
		 
		 
		 List<HotelDTO> temp=this.hotelEAOLocal.getAllHotel();
		 for(HotelDTO h:temp){
			 if (h.isActive()) {
				 this.allHotels.add(h);
			}
		 }
		 for (HotelDTO hDto:this.allHotels){
				 this.isAddhotel.put(hDto.getId(), true); 
		 }
		 
		 List<ExcursionDTO> temp2=this.excursionEAOLocal.getAllExcursion();
		 for(ExcursionDTO e:temp2){
			 if (e.isActive()) {
				 this.allExcursion.add(e);
			}
		 }

		 for (ExcursionDTO eDto:this.allExcursion){
				 this.isAddExcursion.put(eDto.getId(), true);
			}
		 
		 for(Integer i: this.isAddFlight.keySet()){
				System.out.println(i+" :"+ this.isAddFlight.get(i));
			}

	 }
	 /**
	  * create a package with the general info
	  */
	public void CreatePackage(){
		if (!checkId()){
			return; 
		}
		if(!checkName()){
			return;
		}
		
		if (this.check()) {
			this.isConfirmCreation=true;


			List<FlightDTO> flightsChosen=new ArrayList<FlightDTO>();
			List<HotelDTO> hotelsChosen=new ArrayList<HotelDTO>();
			List<ExcursionDTO> excursionChosen=new ArrayList<ExcursionDTO>();
			
			for(Integer i:this.flightToAdd.keySet()){
				flightsChosen.add(this.flightToAdd.get(i));
			}
			for(Integer i:this.hotelsToAdd.keySet()){
				hotelsChosen.add(this.hotelsToAdd.get(i));
			}
			for(Integer i:this.excursionToAdd.keySet()){
				excursionChosen.add(this.excursionToAdd.get(i));
			}
			this.travelPackageDTO.setPackageFlights(flightsChosen);
			this.travelPackageDTO.setPackageHotelDTOs(hotelsChosen);
			this.travelPackageDTO.setPackageExcursions(excursionChosen);
			
			
		}

	}
	

	private boolean checkId(){
		boolean value=true;
		this.errorIdAlreadyExist="";
		List<TravelPackageDTO> allPackageDTOs=this.travelPackageActionEAOLocal.getAllPackages();
		for(TravelPackageDTO tDto:allPackageDTOs){
			if(this.travelPackageDTO.getId()==tDto.getId()){
				value=false;
				this.errorIdAlreadyExist="id alreasy exist";
				
			}		
			
		}
		return value;
	}
	
	private boolean checkName(){
		boolean value=true;
		List<TravelPackageDTO> allPackageDTOs=this.travelPackageActionEAOLocal.getAllPackages();
		for(TravelPackageDTO tDto:allPackageDTOs){
			if(this.travelPackageDTO.getPackageName().equals(tDto.getPackageName())){
				value=false;
				this.errorNameAlreadyExist="Package name alreasy exist";
				
			}else {
				this.errorNameAlreadyExist="";
			}
		}
		return value;
	}
	
	public void confirmCreation(){
		this.packageCreation.createNewPackage(this.travelPackageDTO);
		this.travelPackageDTO=new TravelPackageDTO();
		this.isConfirmCreation=false;


	}
	
	public void cancelCreation(){
		this.isConfirmCreation=false;
	}
	
	private boolean check(){
		boolean verified;
		boolean verifiedNumber;
		verifiedNumber=true;
		verified=true;
		
		if(this.travelPackageDTO.getId()==0){
			this.errorPackageId="package ID not valid";
			verifiedNumber=false;
			}
		
		else {
			this.errorPackageId="";
		}
		
		if(this.travelPackageDTO.getNumberOfPerson()==0){
			this.errorNumberPerson="package number of person not valid";
			verifiedNumber=false;
		}else {
			this.errorNumberPerson="";
		}
		
		if (!verifiedNumber) {
			return false;
		}
		
		if (this.flightToAdd.keySet().size()<2) {
			this.errorFlight="you must choose at least two flights";
			verified=false;
		}else {
			this.errorFlight="";
		}
		
		if (this.hotelsToAdd.keySet().size()<1) {
			this.errorHotel="you must choose at least one hotel";
			verified=false;
		}else {
			this.errorHotel="";
		}
		if (this.excursionToAdd.keySet().size()<1) {
			this.errorExcursion="you must choose at least one excursion";
			verified=false;
		} else {
			this.errorExcursion="";
		}
		
		
		if (verified) {
			return true;
		}
		return false;
	}
	
	
	public void addFlight(FlightDTO flightToAdd){
		
		System.out.println("flihgt to add: "+flightToAdd.getId());
		this.flightToAdd.put(flightToAdd.getId(), flightToAdd);
		System.out.println(this.flightToAdd.keySet());
		this.isAddFlight.put(flightToAdd.getId(), false);
		for(Integer i: this.isAddFlight.keySet()){
			System.out.println(i+" :"+ this.isAddFlight.get(i));
		}
	
	
	}
	
	public void removeFlight(FlightDTO flightToRemove){
		this.flightToAdd.remove(flightToRemove.getId());
		this.isAddFlight.put(flightToRemove.getId(), true);
	}
	
	
	public void addHotel(HotelDTO hotelToAdd){
		this.hotelsToAdd.put(hotelToAdd.getId(), hotelToAdd);
		this.isAddhotel.put(hotelToAdd.getId(), false);
		
	}
	
	public void removeHotel(HotelDTO hotelToRemove){
		this.hotelsToAdd.remove(hotelToRemove.getId());
		this.isAddhotel.put(hotelToRemove.getId(), true);
	}
	
	public void addExcursion(ExcursionDTO excursionToAdd){
		this.excursionToAdd.put(excursionToAdd.getId(), excursionToAdd);
		this.isAddExcursion.put(excursionToAdd.getId(), false);

	
	}
	
	public void removeExcursion(ExcursionDTO excursionToRemove){
		this.excursionToAdd.remove(excursionToRemove.getId());
		this.isAddExcursion.put(excursionToRemove.getId(), true);
	}
	
	
	
	
	/**getter and setter*/

	
	public TravelPackageDTO getTravelPackageDTO() {
		return travelPackageDTO;
	}

	public String getErrorHotel() {
		return errorHotel;
	}

	public String getErrorFlight() {
		return errorFlight;
	}

	public HashMap<Integer, Boolean> getIsAddhotel() {
		return isAddhotel;
	}

	public void setIsAddhotel(HashMap<Integer, Boolean> isAddhotel) {
		this.isAddhotel = isAddhotel;
	}



	public HashMap<Integer, HotelDTO> getHotelsToAdd() {
		return hotelsToAdd;
	}

	public void setHotelsToAdd(HashMap<Integer, HotelDTO> hotelsToAdd) {
		this.hotelsToAdd = hotelsToAdd;
	}

	public HashMap<Integer, FlightDTO> getFlightToAdd() {
		return flightToAdd;
	}

	public void setFlightToAdd(HashMap<Integer, FlightDTO> flightToAdd) {
		this.flightToAdd = flightToAdd;
	}

	public void setTravelPackageDTO(TravelPackageDTO travelPackageDTO) {
		this.travelPackageDTO = travelPackageDTO;
	}



	public HashMap<Integer,Boolean> getIsAdd() {
		return isAddFlight;
	}

	public void setIsAdd(HashMap<Integer,Boolean> isAdd) {
		this.isAddFlight = isAdd;
	}



	public List<FlightDTO> getAllflights() {
		return allflights;
	}

	public void setAllflights(List<FlightDTO> allflights) {
		this.allflights = allflights;
	}

	public String getErrorPackageId() {
		return errorPackageId;
	}

	public void setErrorPackageId(String errorPackageId) {
		this.errorPackageId = errorPackageId;
	}

	public String getErrorNumberPerson() {
		return errorNumberPerson;
	}

	public void setErrorNumberPerson(String errorNumberPerson) {
		this.errorNumberPerson = errorNumberPerson;
	}

	public boolean isConfirmCreation() {
		return isConfirmCreation;
	}

	public void setConfirmCreation(boolean isConfirmCreation) {
		this.isConfirmCreation = isConfirmCreation;
	}

	public boolean isExcursion() {
		return isExcursion;
	}

	public void setExcursion(boolean isExcursion) {
		this.isExcursion = isExcursion;
	}

	public List<ExcursionDTO> getAllExcursion() {
		return allExcursion;
	}

	public void setAllExcursion(List<ExcursionDTO> allExcursion) {
		this.allExcursion = allExcursion;
	}

	public HashMap<Integer, Boolean> getIsAddExcursion() {
		return isAddExcursion;
	}

	public void setIsAddExcursion(HashMap<Integer, Boolean> isAddExcursion) {
		this.isAddExcursion = isAddExcursion;
	}

	public HashMap<Integer, ExcursionDTO> getExcursionToAdd() {
		return excursionToAdd;
	}

	public void setExcursionToAdd(HashMap<Integer, ExcursionDTO> excursionToAdd) {
		this.excursionToAdd = excursionToAdd;
	}

	public String getErrorExcursion() {
		return errorExcursion;
	}

	public void setErrorExcursion(String errorExcursion) {
		this.errorExcursion = errorExcursion;
	}

	public String getErrorIdAlreadyExist() {
		return errorIdAlreadyExist;
	}

	public void setErrorIdAlreadyExist(String errorIdAlreadyExist) {
		this.errorIdAlreadyExist = errorIdAlreadyExist;
	}

	public String getErrorNameAlreadyExist() {
		return errorNameAlreadyExist;
	}

	public void setErrorNameAlreadyExist(String errorNameAlreadyExist) {
		this.errorNameAlreadyExist = errorNameAlreadyExist;
	}

	public List<CityDTO> getCityDTOs() {
		return cityDTOs;
	}

	public void setCityDTOs(List<CityDTO> cityDTOs) {
		this.cityDTOs = cityDTOs;
	}

	public List<HotelDTO> getAllHotels() {
		return allHotels;
	}

	public void setAllHotels(List<HotelDTO> allHotels) {
		this.allHotels = allHotels;
	}



}
